package com.jx.gocomtask.webservice.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import com.jx.gocomtask.webservice.DTO.*;
import com.jx.gocomtask.webservice.DTO.UserInfoList.UserInfo;
import com.jx.gocomtask.webservice.DTO.query.MessageQuery;
import com.jx.gocomtask.webservice.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.jx.gocomtask.utils.JacksonUtil;
import com.jx.gocomtask.webservice.entity.ExtTaskMessage;
import com.jx.gocomtask.webservice.entity.ExtTaskUser;
import com.jx.gocomtask.webservice.repository.ExtTaskMessageRepository;
import com.jx.gocomtask.webservice.service.Route;
import com.jx.gocomtask.webservice.service.RouteExt;
import com.jx.gocomtask.webservice.service.SystemSuperApp;
@Service
public class RouteService implements Route {
	private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RouteService.class);
	public static class  Segment{
		private List<UserInfoList.UserInfo> sameUserInfo=new ArrayList<>();
		private String text;
		private TaskScope taskScope = TaskScope.OTHER;
		public List<UserInfoList.UserInfo> getSameUserInfo() {
			return sameUserInfo;
		}
		
		public String getText() {
			return text;
		}
		public void setText(String text) {
			this.text = text;
		}

		public TaskScope getTaskScope() {
			return taskScope;
		}

		public void setTaskScope(TaskScope taskScope) {
			this.taskScope = taskScope;
		}
	}
	private static final String DELIMITER="!*~*!";
	private final String method_single="message/single/send/status?";
	private final String method_group="message/groupapp/send/status?";
	@Resource(name="apiurl")
	String gocomeApiUrl;
	@Resource(name="serviceUrl")
	String serviceUrl;
	@Resource(name="serviceIosUrl")
	String serviceIosUrl;
	@Resource(name="serviceAndroidUrl")
	String serviceAndroidUrl;
	@Resource(name="defaultAppId")
	String defaultAppId;
	@Resource(name="defaultGroupAppId")
	String  defaultGroupAppId;
	@Autowired
	RestTemplate restTemplate;
	@Autowired
	SystemSuperApp systemSuperApp;
	@Resource
	GroupService groupService;
	@Autowired
	ExtTaskMessageRepository extTaskMessageRepository;
	@Resource
	SendMessageService sendMessageService;
	@Resource
	ExtTaskMessageService extTaskMessageService;
	@Autowired
	RouteExt routeExt;
	@Override
	public void messageHandle(GroupPostMessage postMessage) {
		String content=postMessage.getContent();
		if(StringUtils.isBlank(content)){
			return;
		}
//		添加上下文
		addContext(postMessage);
		String form = "OTHER";//ALL:全体成员，OTHER：部分成员，ONESELF：自己
//		todo 需要沟通标识问题
		if (content.contains("@5")){
			form = "ONESELF";
			content = handel5(content, postMessage.getFromUserName());
		}
		if(content.indexOf(DELIMITER)<0){
			return;
		}
		if(content.contains("@全体成员") &&
				content.substring(content.indexOf(DELIMITER)).contains("all"))
			form = "ALL";
		List<Segment> segments = this.getSegments(content, form);
//		消息保存
		if(null == segments || segments.size() == 0)
			return;

		//saveExtTaskMessage(postMessage, segments, form);
		routeExt.saveExtTaskTodo(postMessage, this, segments, form);
	}


	private void addContext(GroupPostMessage postMessage){
		MessageQuery query = new MessageQuery();
		query.userId = postMessage.getFromUserName();
		query.userName = this.takeUserInfo(query.userId);
		query.group = postMessage.getGroup();
//			todo 后续会有微信，暂时默认为gocom
		query.source = 0;
		String content = postMessage.getContent();
		if(StringUtils.isEmpty(content))
			return;

		if (content.contains(DELIMITER))
			content = content.substring(0, content.indexOf(DELIMITER));
		extTaskMessageService.addContent(query, content, query.source);
	}

//	@5处理
	public String handel5(String context, String user){
		String userName = takeUserInfo(user);

//		context = context.replace("@5", "@"+userName);
		if(context.contains(DELIMITER)) {
//			只要包含@5就只为自己，如果有其他人则不通知
			context = context.substring(0, context.indexOf(DELIMITER));
		}
		context ="@"+userName + context + DELIMITER + user;
		return context;
	}
//	根据内容获取tousers
	String header = null;
	private List<Segment> getSegments(String content, String form){
		String[] idlist=StringUtils.split(content, DELIMITER);
		header=idlist[0].trim();
		String tail=idlist[1];
		String[] ids=StringUtils.split(tail, ",");
		UserBatch userBatch=new UserBatch(ids);
		String rt = null;
		UserInfoList userInfos = new UserInfoList();
		rt = restTemplate.postForObject(gocomeApiUrl + "user/info/batchget?"+systemSuperApp.appid_token(defaultAppId),userBatch,String.class);
		userInfos = JacksonUtil.readValue(rt, UserInfoList.class);
		if(Arrays.asList(ids).contains("all")){
			UserInfoList.UserInfo ew=new UserInfoList.UserInfo();
			ew.setTruename("全体成员");
			ew.setUserid("all");
			userInfos.getUser_info_list().add(ew);
		}

		TreeMap<Integer,UserInfoList.UserInfo> poits=parseContent(header,userInfos.getUser_info_list());
		List<Integer> setKeys=new ArrayList<>(poits.keySet());
		if(setKeys.size()<1){
			logger.info("{} 没有找到对应ID",header);
			return null;
		}

		if(setKeys.get(0)==0){
			return fromHead(poits,header);
		}else{
			return fromTail(poits,header);
		}
	}

	private List<UserInfoList.UserInfo> distinct(List<UserInfoList.UserInfo> sameUserInfo){
		int tt=0;
		for(UserInfoList.UserInfo userInfo_:sameUserInfo){
			if(userInfo_.getUserid().equals("all")){
				tt++;
				break;
			}
		}
		if(tt>0){
			sameUserInfo.clear();
			UserInfoList.UserInfo ew=new UserInfoList.UserInfo();
			ew.setTruename("全体成员");
			ew.setUserid("all");
			sameUserInfo.add(ew);
			return sameUserInfo;
		}else{
			return new ArrayList<UserInfoList.UserInfo>(new HashSet<UserInfoList.UserInfo>(sameUserInfo));
		}
	}
	private List<Segment> fromHead(TreeMap<Integer,UserInfoList.UserInfo> poits,String text){
		List<Segment> segments= new ArrayList<>();
		List<Integer> setKeys=new ArrayList<>(poits.keySet());
		List<UserInfoList.UserInfo> sameUserInfo=new ArrayList<>();
		for(int i=0;i<setKeys.size();i++){
			UserInfoList.UserInfo userInfo=poits.get(setKeys.get(i));
			String str="";
			int start=setKeys.get(i);
			if(i+1<setKeys.size()){
				str=text.substring(start, setKeys.get(i+1));
			}else{
				str=text.substring(start);
			}
			str=str.replaceAll(userInfo.getTruename(), "").trim();
			sameUserInfo.add(userInfo);
			if(!str.equals("")){
				sameUserInfo=this.distinct(sameUserInfo);
				Segment segment=new Segment();
				segment.getSameUserInfo().addAll(sameUserInfo);
				sameUserInfo.clear();
				segment.text=str;
				segments.add(segment);
			}
		}
		return segments;
	}
	private List<Segment>  fromTail(TreeMap<Integer,UserInfoList.UserInfo> poits,String text){
		List<Segment> segments= new ArrayList<>();
		List<Integer> setKeys=new ArrayList<>(poits.keySet());
		List<UserInfoList.UserInfo> sameUserInfo=new ArrayList<>();
		for(int i=setKeys.size()-1;i>-1;i--){
			UserInfoList.UserInfo userInfo=poits.get(setKeys.get(i));
			String atName=userInfo.getTruename();
			String str="";
			int start=setKeys.get(i)+atName.length();
			if(i>0){
				UserInfoList.UserInfo userInfo_n=poits.get(setKeys.get(i-1));
				int nextpoint=setKeys.get(i-1)+userInfo_n.getTruename().length();
				str=text.substring(nextpoint, start);
			}else{
				str=text.substring(0,start);
			}
			str=str.replaceAll(userInfo.getTruename(), "").trim();
			sameUserInfo.add(userInfo);
			if(!str.equals("")){
				sameUserInfo=this.distinct(sameUserInfo);
				Segment segment=new Segment();
				segment.getSameUserInfo().addAll(sameUserInfo);
				sameUserInfo.clear();
				segment.text=str;
				segments.add(segment);
			}
		}
		return segments;
	}


	private void  saveExtTaskMessage(GroupPostMessage postMessage,List<Segment> segments, String form){
		TaskScope taskScope = TaskScope.OTHER;
		if("ALL".equals(form)) {
			String url = gocomeApiUrl + "groupapp/group/member/list?" + systemSuperApp.appid_token(defaultGroupAppId);
			url = url + "&groupid=" + postMessage.getGroup();
			String rt = restTemplate.postForObject(url, null, String.class);
			List<UserInfoList.UserInfo> userinfo_s = JacksonUtil.toList(rt, UserInfoList.UserInfo.class);

			for(Segment segment : segments) {
				Boolean isAll = false;
				for(UserInfoList.UserInfo info : segment.getSameUserInfo()){
					if(info.getUserid().equals("all")){
						isAll = true;
					}
				}
				if(isAll)
					segment.getSameUserInfo().addAll(userinfo_s);
			}
		}
		if("ONESELF".equals(form))
			taskScope = TaskScope.MYSELF;

		List<ExtTaskMessage> messageList = new LinkedList<>();
		for(Segment segment : segments) {
			if(!"ONESELF".equals(form))
				taskScope = TaskScope.OTHER;
			ExtTaskMessage extTaskMessage = new ExtTaskMessage();
			extTaskMessage.setGroup(postMessage.getGroup());
			extTaskMessage.setFrom(postMessage.getFrom());
			extTaskMessage.setMessageType(postMessage.getMsgType());
			extTaskMessage.setFromUser(postMessage.getFromUserName());
			extTaskMessage.setFromUserTrueName(takeUserInfo(postMessage.getFromUserName()));
			extTaskMessage.setContent(segment.getText());
			extTaskMessage.setStatus(TaskStatus.START);

			String uuid = UUID.randomUUID().toString();
			extTaskMessage.setUuid(uuid);
			extTaskMessage.setIos(serviceIosUrl+"&taskId="+uuid);
			extTaskMessage.setUrl(serviceUrl+"&taskId="+uuid);
			extTaskMessage.setAndroid(serviceAndroidUrl+"&taskId="+uuid);

			List<ExtTaskUser> userLinkedList = new LinkedList<ExtTaskUser>();
			for(UserInfoList.UserInfo userInfo : segment.getSameUserInfo()) {
				if((("all".equals(userInfo.getUserid()) && "@全体成员".equals(userInfo.getTruename()))
						|| (form.equals("ALL") && userInfo.getUserid().equals(postMessage.getFromUserName())))) {
					taskScope = TaskScope.ALL;
					continue;
				}
				if(null == userInfo.getUsername())
					userInfo.setUsername(userInfo.getTruename().replace("@", ""));
				ExtTaskUser taskUser = new ExtTaskUser();
				taskUser.setExtTaskMessage(extTaskMessage);
				taskUser.setTaskUser(userInfo.getUserid());
				taskUser.setTaskUserName(userInfo.getUsername());
				taskUser.setStatus(TaskStatus.START);
				userLinkedList.add(taskUser);
			}

			extTaskMessage.setScope(taskScope);
			extTaskMessage.setExtTaskUser(userLinkedList);

			//extTaskMessage.setStatusMessage(changeContent(extTaskMessage, postMessage, segment.getText()));
			extTaskMessage.setStatusMessage(changeContent(extTaskMessage));
			extTaskMessage.setPostMessage(postMessage);
//			发送消息
			extTaskMessage = this.preSaveExtTaskMessage(extTaskMessage);

			messageList.add(extTaskMessage);
		}
		extTaskMessageRepository.save(messageList);
	}
	@Override
	public  ExtTaskMessage  preSaveExtTaskMessage(ExtTaskMessage extTaskMessage){
		StatusMessage sm_single=extTaskMessage.getStatusMessage();
		String url=extTaskMessage.getUrl();
		String ios=extTaskMessage.getIos();
		String android=extTaskMessage.getAndroid();
		sm_single.getBegin().setUrl(url);
		sm_single.getBegin().setIos(ios);
		sm_single.getBegin().setAndroid(android);
		StatusMessage sm_group=sm_single;
		try {
			 sm_group=(StatusMessage)sm_single.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		sm_single.setTogroup(null);
		sm_group.setTouser(null);

//		自己的时候只发送一次就可以
		if(!extTaskMessage.getScope().equals(TaskScope.MYSELF)) {
			for (ExtTaskUser taskUser : extTaskMessage.getExtTaskUser()) {
				if (taskUser.getTaskUser().equals(extTaskMessage.getFromUser()))
					continue;
				sm_single.setTouser(taskUser.getTaskUser());
				sm_single.setTousers(null);
				MessageReturn id_single = sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), sm_single);
				taskUser.setGocomEMsgId(id_single.getId() == null ? "0" : id_single.getId());
			}
		}
		sm_single.setTouser(extTaskMessage.getFromUser());
		 //sm_single.setTouser(extTaskMessage.getPostMessage().getFromUserName());
		 MessageReturn id_creat=sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), sm_single);
		 extTaskMessage.setGocomCMsgId(id_creat.getId());

		return extTaskMessage;
//		todo 减少群内
//		 MessageReturn id_group=sendMessageService.sendMessage(sendUrl(defaultGroupAppId,method_group),sm_group);
//		 extTaskMessage.setGocomGMsgId(id_group.getId());
	}
	@Override
	public boolean  preUpadeContentExtTaskMessage(ExtTaskMessage extTaskMessage){
		TaskStatus taskStatus=extTaskMessage.getStatus();
		if(taskStatus.ordinal()>TaskStatus.RECEIVED.ordinal()){
			return false;
		}
		return true;
	}
	@Override
	public ExtTaskMessage  upadeContentSendExtTaskMessage(ExtTaskMessage extTaskMessage){
		List<ExtTaskUser> extTaskUsers = extTaskMessage.getExtTaskUser();
		if(null == extTaskUsers || extTaskUsers.size() == 0)
			return extTaskMessage;
		StatusMessage statusMessage = null;

		List<String> tousers = new LinkedList<>();
		String touserName = "";
		for (ExtTaskUser userInfo : extTaskMessage.getExtTaskUser()) {
			tousers.add(userInfo.getTaskUser());
			touserName += userInfo.getTaskUserName() + ",";
		}
		touserName = touserName.substring(0, touserName.lastIndexOf(","));
		if (touserName.contains("全体成员")) {
			touserName = "全体成员";
		}

		if(extTaskMessage.getScope() == TaskScope.ALL)
			touserName = "全体成员";

		for(ExtTaskUser extTaskUser : extTaskUsers) {
			if(extTaskMessage.getFromUser().equals(extTaskUser.getTaskUser()))
				continue;
			List<ExtTaskUser> extTaskUserList = new LinkedList<>();
			extTaskUserList.add(extTaskUser);
			extTaskMessage.setExtTaskUser(extTaskUserList);
			statusMessage = sendMessageService.updateStatusMessage(extTaskMessage, "person", touserName);
			statusMessage.setTouser(extTaskUser.getTaskUser());
			MessageReturn id_single = sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), statusMessage);
			if (id_single.getId() != null) {
				extTaskUser.setGocomEMsgId(id_single.getId());
			}
		}
		extTaskMessage.setExtTaskUser(extTaskUsers);

		statusMessage = sendMessageService.updateStatusMessage(extTaskMessage, "create", touserName);
		statusMessage.setTouser(extTaskMessage.getFromUser());
		MessageReturn id_creat = sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), statusMessage);
		if(id_creat.getId()!=null){
			 extTaskMessage.setGocomCMsgId(id_creat.getId());
		 }
		return extTaskMessage;
//		todo 减少群内
//		 MessageReturn id_group=sendMessageService.sendMessage(sendUrl(defaultGroupAppId, method_group), updateStatusMessage(extTaskMessage, "group", extTaskMessage.getContent()));
//		 if(id_group.getId()!=null){
//			 extTaskMessage.setGocomGMsgId(id_group.getId());
//		 }
	}
	//preUpadeStatusExtTaskMessage
	@Override
	public ExtTaskMessage  preUpadeStatusExtTaskMessage(ExtTaskMessage extTaskMessage){
		if(null == extTaskMessage.getExtTaskUser() ||
				extTaskMessage.getExtTaskUser().size() == 0)
			return extTaskMessage;
		StatusMessage statusMessage = null;

		List<String> tousers = new LinkedList<>();
		String touserName = "";
		for (ExtTaskUser userInfo : extTaskMessage.getExtTaskUser()) {
			tousers.add(userInfo.getTaskUser());
			touserName += userInfo.getTaskUserName() + ",";
		}
		touserName = touserName.substring(0, touserName.lastIndexOf(","));
		if (touserName.contains("全体成员")) {
			touserName = "全体成员";
		}

		if(extTaskMessage.getScope() == TaskScope.ALL)
			touserName = "全体成员";


		for(ExtTaskUser extTaskUser : extTaskMessage.getExtTaskUser()) {
			if(extTaskMessage.getFromUser().equals(extTaskUser.getTaskUser()))
				continue;
			List<ExtTaskUser> extTaskUserList = new LinkedList<>();
			extTaskUserList.add(extTaskUser);
			extTaskMessage.setExtTaskUser(extTaskUserList);
			statusMessage = sendMessageService.updateStatusMessage(extTaskMessage, "person", touserName);
			statusMessage.setTouser(extTaskUser.getTaskUser());
			statusMessage.setTousers(null);
			MessageReturn id_single = sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), statusMessage);
//			MessageReturn id_single = sendMessageService.sendMessage(sendUrl(defaultAppId, method_single), updateStatusMessage(extTaskMessage, "person", extTaskMessage.getContent()));
			if (id_single.getId() != null) {
				extTaskUser.setGocomEMsgId(id_single.getId());
			}
		}
		statusMessage = sendMessageService.updateStatusMessage(extTaskMessage, "create", touserName);
		statusMessage.setTouser(extTaskMessage.getFromUser());
		MessageReturn id_creat = sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), statusMessage);
		if(id_creat.getId()!=null){
			extTaskMessage.setGocomCMsgId(id_creat.getId());
		}
		return extTaskMessage;
//		todo 减少群内
//		sendMessageService.sendMessage(sendUrl(defaultGroupAppId,method_group),updateStatusMessage(extTaskMessage,"group"));
	}
	@Override
	public  StatusMessage changeContent(ExtTaskMessage extTaskMessage){
		StatusMessage statusMessage = new StatusMessage();
		//statusMessage.setTogroup(postMessage.getGroup());
		statusMessage.setTogroup(extTaskMessage.getGroup());
		List<String> tousers = new LinkedList<>();
		String touserName = "";
		if(extTaskMessage.getExtTaskUser()!=null){
			tousers =extTaskMessage.getExtTaskUser().stream().map(etu->etu.getTaskUser()).collect(Collectors.toList());
			touserName=extTaskMessage.getExtTaskUser().stream().map(etu->etu.getTaskUserName()).collect(Collectors.joining(","));
		}
		//List<UserInfoList.UserInfo> userInfoList2=extTaskMessage.getExtTaskUser()
		/*for(UserInfoList.UserInfo userInfo : userInfoList){
			tousers.add(userInfo.getUserid());
			touserName += userInfo.getTruename().replace("@", "") + ",";
		}*/
		//touserName = touserName.substring(0, touserName.lastIndexOf(","));
		if(extTaskMessage.getScope()==TaskScope.ALL){
			touserName = "全体成员";
		}
	/*	if(touserName.contains("全体成员")){
			touserName = "全体成员";
		}*/
		statusMessage.setTousers(tousers);
		StatusMessage.Begin begin=new StatusMessage.Begin();
		StatusMessage.Content contentext=new StatusMessage.Content();
		List<StatusMessage.Form> forms=new ArrayList<>();
		contentext.setTitle(extTaskMessage.getStatus().getDescTittle());
		contentext.setDetail(extTaskMessage.getContent());
		//contentext.setDetail(str);
		//forms.add(new StatusMessage.Form("发起人", takeUserInfo(postMessage.getFromUserName())));
		forms.add(new StatusMessage.Form("发起人", extTaskMessage.getFromUserTrueName()));
		forms.add(new StatusMessage.Form("接收人", touserName));
		//forms.add(new StatusMessage.Form("来  源", groupService.findByGuId(postMessage.getGroup()).getGroupname()));
		
		forms.add(new StatusMessage.Form("来  源",  groupService.findByGuId(extTaskMessage.getGroup()).getGroupname()));
		contentext.setForm(forms);
		begin.setContent(contentext);
		begin.setUrl(extTaskMessage.getUrl());
		begin.setIos(extTaskMessage.getIos());
		begin.setAndroid(extTaskMessage.getAndroid());
		statusMessage.setBegin(begin);
		return statusMessage;
	}
	@Override
	public String takeUserInfo(String userid){
		String url=gocomeApiUrl + "user/info?"+systemSuperApp.appid_token(defaultAppId);
		url+="&userid="+userid;
		UserSigleInfo usersigleinfo= restTemplate.postForObject(url,null,UserSigleInfo.class);
		if(usersigleinfo.getUserinfo()==null){
			return userid;
		}
		if(usersigleinfo.getUserinfo().getTruename()==null){
			return userid;
		}
		return usersigleinfo.getUserinfo().getTruename().substring(1);
	}
	private static void readWord ( String input, UserInfoList.UserInfo word, int offset, Map<Integer,UserInfoList.UserInfo> poits ){
		offset = input.indexOf (word.getTruename(), offset);
		if (offset != -1){
			poits.put(offset,word);
			readWord (input, word, ++offset, poits);
		}
	}
	private TreeMap<Integer,UserInfoList.UserInfo> parseContent(String content,List<UserInfoList.UserInfo>userInfos){
		TreeMap<Integer,UserInfoList.UserInfo> poits=new TreeMap<>(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				if (o1 == null || o2 == null)
                    return 0; 
				return Integer.valueOf(o1).compareTo(o2);
			}
			
		});
		for(UserInfoList.UserInfo userInfo:userInfos){
			readWord(content,userInfo,0,poits);
		}
		return poits;
	}

}
